1. Medal Counts over time
library(ggplot2)
library(ggplot2)
library(DT)
library(dplyr)
Attaching package: ‘dplyr’
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
library(ggplot2)
library(DT)
library(dplyr)
library(plotly)
Attaching package: ‘plotly’
The following object is masked from ‘package:ggplot2’:
last_plot
The following object is masked from ‘package:stats’:
filter
The following object is masked from ‘package:graphics’:
layout
- Combine the information in the three spreadsheets
athletes_and_events.csv, noc_regions.csv, and gdp_pop.csv. Note, that the noc_regions.csv is the set all NOC regions, while gdp_pop.csv only contains a snapshot of the current set of countries. You have to decide what to do with some countries that competed under different designations in the past (e.g. Germany and Russia) and some defunct countries and whether and how to combine their totals. Make sure to be clear about your decisions here, so that the editor (and potentially a user of your visualizations) understands what you did.
Decision: Keep original names because the boundaries of the countries often change with the name changes. For example, the Soviet Union consisted of Russia and several other countries, as did Yugoslavia. Conversely, West Germany and East Germany combined to form Germany.
- Calculate a summary of how many summer games each country competed in, and how many medals of each type the country won. Use that summary to provide a visual comparison of medal count by country.
Feel free to focus on smaller set of countries (say the top 10), highlight the United States or another country of your choice, consider gender of the medal winners etc. to make the visualization interesting.
Please provide one visualization showing an over time comparison and one in which a total medal count (across all Summer Olympics) is used. Briefly discuss which visualization you recommend to your editor and why.
How many summer games did each country commpete in?
summer = filter(master, Season == "Summer")
by_year = summer %>%
group_by(Year, NOC, add = TRUE)
by_year = by_year %>% select(Year, NOC)
by_year = unique(by_year)
num_summerolympics = table(by_year$NOC)
num_summerolympics = data.frame(num_summerolympics)
names(num_summerolympics) <- c("NOC", "Number")
#sorted by number of olympics they participated in
nums_sorted = num_summerolympics[order(num_summerolympics$Number, decreasing=T),]
datatable(nums_sorted)
How many medals of each type did each country win?
summer_medal = subset(summer, Medal != 'NA')
summer_medal
by_medal = summer_medal %>%
group_by(Medal, NOC)
num_medal = table(by_medal$Medal, by_medal$NOC)
num_medal = data.frame(num_medal)
names(num_medal) <- c("Medal", "NOC", "Number")
#Extracting medal data for 10 countries
NOCs = c("USA", "RUS", "GER","AUS", "CHN", "IND", "CAN","NOR", "FIN", "AUT")
summer_top = subset(num_medal, NOC %in% NOCs)
summer_top
summer_top$Medal <- factor(summer_top$Medal,levels = c('Gold', 'Silver', 'Bronze'))
medal_plot = ggplot(summer_top, aes(x=NOC, y=Number, fill=Medal, order=Medal)) + geom_bar(stat='identity') + scale_fill_manual(values=c("gold", "grey", "brown"))
medal_plot + scale_x_discrete(limits=c("USA", "GER","AUS", "CHN","RUS","CAN","NOR", "FIN", "IND","AUT"), labels = c("United States", "Germany","Australia", "China","Russia","Canada","Norway", "Finland", "India","Austria")) + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + xlab('') + ylab('Total Number of Medals') + coord_flip() + ggtitle('Total Medals awarded by Country Accross all Summer Olympics')

By Gender
by_sex = summer_medal %>%
group_by(Sex, NOC)
num_sex = table(by_sex$Sex, by_sex$NOC)
num_sex = data.frame(num_sex)
num_sex
names(num_sex) <- c("Sex", "NOC", "Number")
NOCs = c("USA", "GER","AUS", "CHN","RUS","CAN","NOR", "FIN", "IND","AUT")
num_sex_top = subset(num_sex, NOC %in% NOCs)
num_sex_top
num_sex_top
sex_plot = ggplot(num_sex_top, aes(x=NOC, y=Number,colour=Sex)) + geom_point() + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + scale_x_discrete(limits=c("USA", "GER","AUS", "CHN","RUS","CAN","NOR", "FIN", "IND","AUT"), labels = c("United States", "Germany","Australia", "China","Russia","Canada","Norway", "Finland", "India","Austria")) + xlab('') + ylab('Total Number of Medals') + coord_flip() + ggtitle('Total Medals awarded by Country and Gender Accross all Summer Olympics')
sex_plot

Over Time
NOCs = c('USA', 'RUS', 'AUS', 'CHN')
num_year_comp = table(summer_medal$Year, summer_medal$NOC)
num_year_comp
AFG AHO ALB ALG AND ANG ANT ANZ ARG ARM ARU ASA AUS AUT AZE BAH BAN BAR BDI BEL BEN BER BHU BIH
1896 0 0 0 0 0 0 0 0 0 0 0 0 3 5 0 0 0 0 0 0 0 0 0 0
1900 0 0 0 0 0 0 0 0 0 0 0 0 6 6 0 0 0 0 0 43 0 0 0 0
1904 0 0 0 0 0 0 0 0 0 0 0 0 4 4 0 0 0 0 0 0 0 0 0 0
1906 0 0 0 0 0 0 0 0 0 0 0 0 3 9 0 0 0 0 0 11 0 0 0 0
BIZ BLR BOH BOL BOT BRA BRN BRU BUL BUR CAF CAM CAN CAY CGO CHA CHI CHN CIV CMR COD COK COL COM
1896 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1900 0 0 3 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 1 0
1904 0 0 0 0 0 0 0 0 0 0 0 0 48 0 0 0 0 0 0 0 0 0 0 0
1906 0 0 3 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0
CPV CRC CRO CRT CUB CYP CZE DEN DJI DMA DOM ECU EGY ERI ESA ESP EST ETH EUN FIJ FIN FRA FRG FSM
1896 0 0 0 0 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 0 11 0 0
1900 0 0 0 0 2 0 0 9 0 0 0 0 0 0 0 2 0 0 0 0 0 225 0 0
1904 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0
1906 0 0 0 0 0 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 4 64 0 0
GAB GAM GBR GBS GDR GEO GEQ GER GHA GRE GRN GUA GUI GUM GUY HAI HKG HON HUN INA IND IOA IRI IRL
1896 0 0 9 0 0 0 0 32 0 48 0 0 0 0 0 0 0 0 6 0 0 0 0 0
1900 0 0 107 0 0 0 0 45 0 0 0 0 0 0 0 1 0 0 5 0 2 0 0 0
1904 0 0 2 0 0 0 0 16 0 2 0 0 0 0 0 0 0 0 4 0 0 0 0 0
1906 0 0 39 0 0 0 0 30 0 102 0 0 0 0 0 0 0 0 13 0 0 0 0 0
IRQ ISL ISR ISV ITA IVB JAM JOR JPN KAZ KEN KGZ KIR KOR KOS KSA KUW LAO LAT LBA LBR LCA LES LIB
1896 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1900 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1904 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1906 0 0 0 0 56 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
LIE LTU LUX MAD MAL MAR MAS MAW MDA MDV MEX MGL MHL MKD MLI MLT MNE MON MOZ MRI MTN MYA NAM NBO
1896 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1900 0 0 1 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0
1904 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1906 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
NCA NED NEP NFL NGR NIG NOR NRU NZL OMA PAK PAN PAR PER PHI PLE PLW PNG POL POR PRK PUR QAT RHO
1896 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1900 0 27 0 0 0 0 9 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1904 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1906 0 6 0 0 0 0 25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ROT ROU RSA RUS RWA SAA SAM SCG SEN SEY SGP SKN SLE SLO SMR SOL SOM SRB SRI SSD STP SUD SUI SUR
1896 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0
1900 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 21 0
1904 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0
1906 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 12 0
SVK SWE SWZ SYR TAN TCH TGA THA TJK TKM TLS TOG TPE TTO TUN TUR TUV UAE UAR UGA UKR UNK URS URU
1896 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1900 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1904 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1906 0 21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
USA UZB VAN VEN VIE VIN VNM WIF YAR YEM YMD YUG ZAM ZIM SIN ROM TRI
1896 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1900 63 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1904 394 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1906 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[ reached getOption("max.print") -- omitted 25 rows ]
num_year_comp = data.frame(num_year_comp)
num_year_comp
names(num_year_comp) = c("Year", "NOC", "Number")
num_year_comp
num_year_comp = subset(num_year_comp,NOC %in% NOCs)
num_year_comp
num_year_comp$Year = substring(as.Date(num_year_comp$Year, format = "%Y"), 0,4)
num_year_comp
num_year_comp = subset(num_year_comp, Year >= 1984)
year_plot1 = ggplot(num_year_comp, aes(x=Year, y=Number, group = NOC, colour = NOC)) + geom_point() + geom_line()
year_plot1 + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + xlab('') + ylab('Total Number of Medals') + scale_colour_discrete(guide = guide_legend(reverse=TRUE, title=NULL), labels=c("Australia", "China", "Russia", "United States")) + ggtitle('Total Medals awarded by Country and Year')

2. Medal Counts adjusted by Population, GDP
There are different ways to calculate “success”. Consider the following variants and choose one (and make sure your choice is clear in the visualization):
- Just consider gold medals.
- Simply add up the number of medals of different types.
- Create an index in which medals are valued differently. (gold=3, silver=2, bronze=1).
- A reasonable other way that you prefer.
Now, adjust the ranking of medal success by (a) GDP per capita and (b) population. You have now three rankings: unadjusted ranking, adjusted by GDP per capita, and adjusted by population.
Visualize how these rankings differ. Feel free to highlight a specific pattern (e.g. “South Korea – specialization reaps benefits” or “The superpowers losing their grip”).
num_year_comp = table(summer_medal$Year, summer_medal$Medal, summer_medal$NOC)
num_year_comp = data.frame(num_year_comp)
names(num_year_comp) = c("Year", "Medal", "NOC", "Number")
NOCs = c("USA", "GER","AUS", "CHN","RUS","CAN","NOR", "FIN", "IND","AUT")
gold_comp = subset(num_year_comp,Medal == 'Gold')
gold_comp = subset(gold_comp,NOC %in% NOCs)
gold_plot = ggplot(gold_comp, aes(x=NOC, y=Number)) + geom_bar(stat='identity', fill = 'gold')
num_year_comp
gold_plot + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + scale_x_discrete(limits=c("USA", "GER","AUS", "CHN","RUS","CAN","NOR", "FIN", "IND","AUT"), labels = c("United States", "Germany","Australia", "China","Russia","Canada","Norway", "Finland", "India","Austria")) + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + xlab('') + ylab('Total Number of Gold Medals') + ggtitle('Total Gold Medals awarded by Country Accross all Summer Olympics')


gold_comp1 <- unique(data.frame(summer_medal_gold$NOC, summer_medal_gold$GDP.per.Capita.x))
names(gold_comp1) = c("NOC", "GDP")
gold_comp = merge(gold_comp1, gold_comp2, by = 'NOC')
gold_comp
gold_comp <- transform(gold_comp, GoldByGDP = Number*1000/(GDP))
gold_comp = subset(gold_comp, GoldByGDP != Inf)
gold_comp
gold_comp = gold_comp[order(gold_comp$GoldByGDP, decreasing=T),]
gold_comp3 <- unique(data.frame(summer_medal_gold$NOC, summer_medal_gold$region))
gold_comp3$NOC = gold_comp3$summer_medal_gold.NOC
gold_comp3$Country = gold_comp3$summer_medal_gold.region
gold_comp = merge(gold_comp, gold_comp3, by = 'NOC')
gold_comp$Country <- gold_comp$summer_medal_gold
gold_comp = subset(gold_comp, NOC != 'URS')
gold_comp = subset(gold_comp, NOC != 'YUG')
gold_comp = gold_comp[order(gold_comp$GoldByGDP, decreasing=T),]
gold_comp$Country = gold_comp$summer_medal_gold.region
gold_pop = data.frame(gold_comp$Country, gold_comp$GoldByGDP)
gold_pop = gold_pop[0:9,]
gold_pop$Country = gold_pop$gold_comp.Country
gold_pop$GoldByGDP = gold_pop$gold_comp.GoldByGDP
gold_pop_plot = ggplot(gold_pop, aes(x=Country, y=GoldByGDP)) + geom_bar(stat='identity', fill = 'gold')
gold_pop_plot + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + theme(axis.text.x = element_text(angle = 90, hjust = 1), axis.title.y=element_text(size=7.5)) + scale_x_discrete(limits=gold_pop$Country) + xlab('') + ylab(' No. of Gold Medals/GDP Per Capita(Thousands)') + ggtitle('Gold Medals to GDP Per Capita Ratio for Countries accross all Summer olympics')

3. Host Country Advantage
Until the 2016 Rio Summer Olympics (our data ends here), there were 23 host cities. Calculate whether the host nation had an advantage. That is calculate whether the host country did win more medals when the Summer Olympics was in their country compared to other times.
Note, that the 23 host cities are noted in the data but not the countries they are located in. This happens commonly and often Wikipedia has the kind of additional data you want for the task. To save you some time, here is a quick way to get this kind of table from Wikipedia into R:
Provide a visualization of the host country advantage (or absence thereof).
countries <- c("Greece", "France", "United States", "United Kingdom", "Sweden", "Belgium", "France", "Netherlands", "United States", "Germany", "United Kingdom", "Finland", "Australia", "Italy", "Japan", "Mexico", "West Germany", "Canada", "Soviet Union", "United States","South Korea", "Spain", "United States", "Australia", "Greece" ,"China","United Kingdom", "Brazil")
host_NOCs <- c("FRG", "FRA", "USA", "GBR", "SWE", "BEL", "FRA", "NED", "USA", "FRG", "GBR", "FIN", "AUS", "ITA", "JPN", "MEX", "FRG", "CAN", "URS", "USA","KOR", "ESP", "USA", "AUS", "GRE" ,"CHN","GBR", "BRA")
summer_medal = subset(summer_medal, Year != 1906)
gold = subset(summer_medal, Medal == 'Gold')
gold_year = table(gold$NOC, gold$Year)
gold_year = data.frame(gold_year)
names(gold_year) = c('NOC', 'Year', 'Number')
years= as.factor(unique(gold$Year))
years = sort(unique(years))
years
[1] 1896 1900 1904 1908 1912 1920 1924 1928 1932 1936 1948 1952 1956 1960 1964 1968 1972 1976 1980 1984
[21] 1988 1992 1996 2000 2004 2008 2012 2016
28 Levels: 1896 1900 1904 1908 1912 1920 1924 1928 1932 1936 1948 1952 1956 1960 1964 1968 1972 ... 2016
hosts = data.frame(sort(unique(years)), c("Greece", "France", "United States", "United Kingdom", "Sweden", "Belgium", "France", "Netherlands", "United States", "Germany", "United Kingdom", "Finland", "Australia", "Italy", "Japan", "Mexico", "West Germany", "Canada", "Soviet Union", "United States","South Korea", "Spain", "United States", "Australia", "Greece" ,"China","United Kingdom", "Brazil"))
num_year_comp = table(gold$Year, gold$NOC)
num_year_comp = data.frame(num_year_comp)
names(num_year_comp) = c("Year", "NOC", "Number")
num_year_comp = subset(num_year_comp, NOC %in% c("FRG", "FRA", "USA", "GBR", "SWE", "BEL", "FRA", "NED", "USA", "FRG", "GBR", "FIN", "AUS", "ITA", "JPN", "MEX", "FRG", "CAN", "URS", "USA","KOR", "ESP", "USA", "AUS", "GRE" ,"CHN","GBR", "BRA"))
olympic_hosts <- function(){
host_row1 = subset(num_year_comp, Year == years[0])
host_row1 = subset(host_row1, NOC == host_NOCs[0])
for (i in 1:29) {
year <- years[i]
NOC1 <- host_NOCs[i]
host_row2 = subset(num_year_comp, Year == year)
host_row2 = subset(host_row2, NOC == NOC1)
host_row1 = rbind(host_row1, host_row2)
}
return(host_row1)
}
average_golds <- function(){
averages = c()
host_row1 = subset(num_year_comp, NOC == host_NOCs[0])
average = mean(host_row1$Number)
averages = append(averages, average)
for (i in 1:29) {
NOC1 <- host_NOCs[i]
host_row2 = subset(num_year_comp, NOC == NOC1)
average = mean(host_row2$Number)
averages = append(averages, average)
}
return(averages)
}
hosts = olympic_hosts()
hosts
averages = average_golds()
length(averages)
[1] 30
averages = averages[-(0:1)]
averages
[1] 5.142857 15.821429 87.857143 22.357143 12.571429 3.357143 15.821429 8.750000 87.857143 5.142857
[11] 22.357143 4.642857 12.214286 17.750000 8.214286 1.071429 5.142857 5.607143 29.714286 87.857143
[21] 6.107143 3.892857 87.857143 12.214286 1.357143 11.928571 22.357143 3.892857 NaN
averages = averages[-length(averages)]
averages
[1] 5.142857 15.821429 87.857143 22.357143 12.571429 3.357143 15.821429 8.750000 87.857143 5.142857
[11] 22.357143 4.642857 12.214286 17.750000 8.214286 1.071429 5.142857 5.607143 29.714286 87.857143
[21] 6.107143 3.892857 87.857143 12.214286 1.357143 11.928571 22.357143 3.892857
hosts$average_over_years = averages
hosts
library(ggplot2)
gold_host = ggplot(hosts, aes(x=NOC)) + geom_bar(stat='identity', fill = 'gold', aes(y=Number)) + geom_bar(stat='identity', fill = 'red', aes(y=average_over_years)) + scale_x_discrete( labels = c("Greece: 1896", "France: 1900", "United States: 1904", "United Kingdom: 1908", "Sweden: 1912", "Belgium: 1920", "France: 1924", "Netherlands: 1928", "United States: 1932", "Germany: 1936", "United Kingdom: 1948", "Finland: 1952", "Australia: 1956", "Italy: 1960", "Japan: 1964", "Mexico: 1968", "West Germany: 1972", "Canada: 1976", "Soviet Union: 1980", "United States: 1984","South Korea: 1988", "Spain: 1992", "United States: 1996", "Australia: 2000", "Greece: 2004" ,"China: 2008","United Kingdom: 2012", "Brazil: 2016")) + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + xlab('') + ylab('Total Number of Gold Medals won by Host')
gold_host + theme(axis.text.x = element_text(angle = 90, hjust = 1), axis.title.y = element_text(size = 8)) +
ggtitle('Host Country Advantage Accross all Summer Olympics')

Note: Red denotes the average medals earned by the host country accross all Summer Olympics. Yellow denotes the number of medals earned by the host country in the Olympics hosted by the country.
4. Most successful athletes
- Now, let’s look at the most successful athletes. Provide a visual display of the most successful athletes of all time.
by_athletes = summer_medal %>%
group_by(Name, Medal, region)
by_athletes = unique(by_athletes)
by_athletes$Country = by_athletes$region
num_athletes = table(by_athletes$Name, by_athletes$Country)
num_athletes = data.frame(num_athletes)
names(num_athletes) <- c("Name", 'Country', "Number")
#sorted by number of medals
nums_sorted = num_athletes[order(num_athletes$Number, decreasing=T),]
nums_sorted = subset(nums_sorted, Number != 0)
nums_sorted1 = nums_sorted[0:30,]
nums_sorted1
athletes_plot = ggplot(nums_sorted1, aes(x=reorder(Name, -Number, reverse =TRUE), y=Number, fill = Country)) + geom_bar(stat='identity')+ xlab('') + ylab('Number of Medals')
athletes_plot + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + coord_flip() + ggtitle('Most Medals won accross all Summer Olympics, by Country(Top 30)')

- Choose one or two additional dimensions among gender, height, weight, sport, discipline, event, year, and country to highlight an interesting pattern in the data.
by_athletes = summer_medal %>%
group_by(Name, Medal, Year, Sex)
by_athletes = unique(by_athletes)
num_athletes = table(by_athletes$Name, by_athletes$Year,by_athletes$Sex)
num_athletes = data.frame(num_athletes)
names(num_athletes) <- c("Name", 'Year',"Sex", "Number")
nums_sorted = subset(nums_sorted, Number != 0)
#sorted by number of medals
nums_sorted = num_athletes[order(num_athletes$Number, decreasing=T),]
nums_sorted1 = nums_sorted[0:30,]
nums_sorted1$Year = substring(as.Date(nums_sorted1$Year, format = "%Y"), 0,4)
nums_sorted1$NameYear <- paste(nums_sorted1$Name,nums_sorted1$Year)
athletes_plot = ggplot(nums_sorted1, aes(x=reorder(NameYear, -Number), y=Number, fill = Sex)) + geom_bar(stat='identity') + xlab('') + ylab('Number of Medals won in a single year: Top 30')
athletes_plot + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + ggtitle('Highest number of medals won in a single Olympics by Gender (Top 30)')

by_athletes = summer_medal %>%
group_by(Name, Medal, Year, Sex)
by_athletes = unique(by_athletes)
5. Make two plots interactive
Choose 2 of the plots you created above and add interactivity. Briefly describe to the editor why interactivity in these visualization is particularly helpful for a reader.
- Number of Medals by Height and Weight: Categorized by athletes who have won medals vs. those that did not. The plot allows for height and weight comparisons and shows that athletes that are outliers are more likely to win. This shows that physical characteristics play a key role in the competition. Interactivity allows for numerical information on the chart since it is hard to read.
- Interactivity added to the earlier plot of Number of medals awarded by gender in the top eleven countries. Interactivity allows the reader to see the exact numbers and hence make numerical comparisons.
summer_medal$Country = summer_medal$region
by_athletes = summer_medal %>%
group_by(Name, Medal, Year, Country, Sex)
by_athletes = unique(by_athletes)
num_athletes = table(by_athletes$Name, by_athletes$Year)
num_athletes = data.frame(num_athletes)
names(num_athletes) <- c("Name", 'Year',"Number")
Sex_Country = unique(data.frame(summer_medal$Name,summer_medal$Sex, summer_medal$Country, summer_medal$Height, summer_medal$Weight, summer_medal$Age))
names(Sex_Country) <- c("Name", 'Sex',"Country", "Height", "Weight", "Age")
num_athletes = merge(num_athletes, Sex_Country, by = 'Name')
num_athletes$won_medal<-ifelse((num_athletes$Number>0), 1, 0)
num_athletes1 = num_athletes[sample(nrow(num_athletes), 10000), ]
library(ggplot2)
library(plotly)
num_athletes1$won_medal = as.factor(num_athletes1$won_medal)
p <- plot_ly(data = num_athletes1, x = ~Weight, y = ~Height, color= ~won_medal)
p
No trace type specified:
Based on info supplied, a 'scatter' trace seems appropriate.
Read more about this trace type -> https://plot.ly/r/reference/#scatter
No scatter mode specifed:
Setting the mode to markers
Read more about this attribute -> https://plot.ly/r/reference/#scatter-mode
Ignoring 2412 observationsminimal value for n is 3, returning requested palette with 3 different levels
No trace type specified:
Based on info supplied, a 'scatter' trace seems appropriate.
Read more about this trace type -> https://plot.ly/r/reference/#scatter
No scatter mode specifed:
Setting the mode to markers
Read more about this attribute -> https://plot.ly/r/reference/#scatter-mode
Ignoring 2412 observationsminimal value for n is 3, returning requested palette with 3 different levels
ggplotly(sex_plot)
6. Data Table
Prepare a selected dataset and add a datatable to the output. Make sure the columns are clearly labelled. Select the appropriate options for the data table (e.g. search bar, sorting, column filters etc.). Suggest to the editor which kind of information you would like to provide in a data table in the online version of the article and why.
summer_medal1 = data.frame(summer_medal$Name, summer_medal$Sex, summer_medal$Country, summer_medal$Year, summer_medal$Medal, summer_medal$Event )
summer_medal1
names(summer_medal1) = c("Name", "Sex", "Country", "Year","Medal", "Event")
DT <- datatable(summer_medal1, class = 'cell-border stripe', rownames =FALSE, options = list(
pageLength = 10, autoWidth = TRUE
), filter = 'top')
DT
It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlIt seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
DT:::DT2BSClass('display')
[1] "table table-striped table-hover"
DT:::DT2BSClass(c('compact', 'cell-border'))
[1] "table table-condensed table-bordered"
DT
It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlIt seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
LS0tCnRpdGxlOiAiSG9tZXdvcmsgMSAtIFN1bW1lciBPbHltcGljcyIKYXV0aG9yOiAiS2FseWFuaSBTdWJiaWFoIgpkYXRlOiAnMjAxOS0wMi0xNycKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKIyMjIyAxLiBNZWRhbCBDb3VudHMgb3ZlciB0aW1lCgpgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KERUKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHBsb3RseSkKYGBgCgphKSBDb21iaW5lIHRoZSBpbmZvcm1hdGlvbiBpbiB0aGUgdGhyZWUgc3ByZWFkc2hlZXRzIGBhdGhsZXRlc19hbmRfZXZlbnRzLmNzdmAsIGBub2NfcmVnaW9ucy5jc3ZgLCBhbmQgIGBnZHBfcG9wLmNzdmAuIE5vdGUsIHRoYXQgdGhlIGBub2NfcmVnaW9ucy5jc3ZgIGlzIHRoZSBzZXQgYWxsIE5PQyByZWdpb25zLCB3aGlsZSBgZ2RwX3BvcC5jc3ZgIG9ubHkgY29udGFpbnMgYSBzbmFwc2hvdCBvZiB0aGUgY3VycmVudCBzZXQgb2YgY291bnRyaWVzLiBZb3UgaGF2ZSB0byBkZWNpZGUgd2hhdCB0byBkbyB3aXRoIHNvbWUgW2NvdW50cmllcyB0aGF0IGNvbXBldGVkIHVuZGVyIGRpZmZlcmVudCBkZXNpZ25hdGlvbnMgaW4gdGhlIHBhc3QgKGUuZy4gR2VybWFueSBhbmQgUnVzc2lhKV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQWxsLXRpbWVfT2x5bXBpY19HYW1lc19tZWRhbF90YWJsZSkgYW5kIHNvbWUgZGVmdW5jdCBjb3VudHJpZXMgYW5kIHdoZXRoZXIgYW5kIGhvdyB0byBjb21iaW5lIHRoZWlyIHRvdGFscy4gTWFrZSBzdXJlIHRvIGJlIGNsZWFyIGFib3V0IHlvdXIgZGVjaXNpb25zIGhlcmUsIHNvIHRoYXQgdGhlIGVkaXRvciAoYW5kIHBvdGVudGlhbGx5IGEgdXNlciBvZiB5b3VyIHZpc3VhbGl6YXRpb25zKSB1bmRlcnN0YW5kcyB3aGF0IHlvdSBkaWQuCgpEZWNpc2lvbjogS2VlcCBvcmlnaW5hbCBuYW1lcyBiZWNhdXNlIHRoZSBib3VuZGFyaWVzIG9mIHRoZSBjb3VudHJpZXMgb2Z0ZW4gY2hhbmdlIHdpdGggdGhlIG5hbWUgY2hhbmdlcy4gRm9yIGV4YW1wbGUsIHRoZSBTb3ZpZXQgVW5pb24gY29uc2lzdGVkIG9mIFJ1c3NpYSBhbmQgc2V2ZXJhbCBvdGhlciBjb3VudHJpZXMsIGFzIGRpZCBZdWdvc2xhdmlhLiBDb252ZXJzZWx5LCBXZXN0IEdlcm1hbnkgYW5kIEVhc3QgR2VybWFueSBjb21iaW5lZCB0byBmb3JtIEdlcm1hbnkuIApgYGB7cn0KYXRoID0gcmVhZC5jc3YoImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9xbXNzLWdyNTA2My0yMDE5L2NvdXJzZV9tYXRlcmlhbHMvbWFzdGVyL0V4ZXJjaXNlcy8wM19vbHltcGljcy9hdGhsZXRlc19hbmRfZXZlbnRzLmNzdj90b2tlbj1BZVlhdExLRWRYelZaTzdRYjZ2cTVNR0Q5dE1zZ3V0NGtzNWNmWWNJd0ElM0QlM0QiKQpub2MgPSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Ftc3MtZ3I1MDYzLTIwMTkvY291cnNlX21hdGVyaWFscy9tYXN0ZXIvRXhlcmNpc2VzLzAzX29seW1waWNzL25vY19yZWdpb25zLmNzdj90b2tlbj1BZVlhdE91Ql9aY2pSUWNoZkhkcjRobXdNdUJJS25JemtzNWNmWWN4d0ElM0QlM0QiKQpnZHAgPSByZWFkLmNzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Ftc3MtZ3I1MDYzLTIwMTkvY291cnNlX21hdGVyaWFscy9tYXN0ZXIvRXhlcmNpc2VzLzAzX29seW1waWNzL2dkcF9wb3AuY3N2P3Rva2VuPUFlWWF0Q0pnZjM5d0VkLXFPbTA1OHVhVmJXdS1uRUJ5a3M1Y2ZZY2l3QSUzRCUzRCIpCmBgYAoKYGBge3J9Cm1hc3RlciA9IG1lcmdlKHggPSBhdGgsIHkgPSBub2MsIGJ5ID0gIk5PQyIsIGFsbD0gVFJVRSkKZ2RwJE5PQyA8LSBnZHAkQ29kZQptYXN0ZXIgPSBtZXJnZSh4ID0gbWFzdGVyLCB5ID0gZ2RwLCBieSA9ICJOT0MiLCBhbGw9IFRSVUUpCm1hc3Rlcj0gdW5pcXVlKG1hc3RlcikKYGBgCgoKCmIpIENhbGN1bGF0ZSBhIHN1bW1hcnkgb2YgaG93IG1hbnkgc3VtbWVyIGdhbWVzIGVhY2ggY291bnRyeSBjb21wZXRlZCBpbiwgYW5kIGhvdyBtYW55IG1lZGFscyBvZiBlYWNoIHR5cGUgdGhlIGNvdW50cnkgd29uLiBVc2UgdGhhdCBzdW1tYXJ5IHRvIHByb3ZpZGUgYSAqKnZpc3VhbCBjb21wYXJpc29uIG9mIG1lZGFsIGNvdW50IGJ5IGNvdW50cnkqKi4gCgpGZWVsIGZyZWUgdG8gZm9jdXMgb24gc21hbGxlciBzZXQgb2YgY291bnRyaWVzIChzYXkgdGhlIHRvcCAxMCksIGhpZ2hsaWdodCB0aGUgVW5pdGVkIFN0YXRlcyBvciBhbm90aGVyIGNvdW50cnkgb2YgeW91ciBjaG9pY2UsIGNvbnNpZGVyIGdlbmRlciBvZiB0aGUgbWVkYWwgd2lubmVycyBldGMuIHRvIG1ha2UgdGhlIHZpc3VhbGl6YXRpb24gaW50ZXJlc3RpbmcuIAoKUGxlYXNlIHByb3ZpZGUgb25lIHZpc3VhbGl6YXRpb24gc2hvd2luZyBhbiBvdmVyIHRpbWUgY29tcGFyaXNvbiBhbmQgb25lIGluIHdoaWNoIGEgdG90YWwgbWVkYWwgY291bnQgKGFjcm9zcyBhbGwgU3VtbWVyIE9seW1waWNzKSBpcyB1c2VkLiBCcmllZmx5IGRpc2N1c3Mgd2hpY2ggdmlzdWFsaXphdGlvbiB5b3UgcmVjb21tZW5kIHRvIHlvdXIgZWRpdG9yIGFuZCB3aHkuCgotLS0tLS0tCkhvdyBtYW55IHN1bW1lciBnYW1lcyBkaWQgZWFjaCBjb3VudHJ5IGNvbW1wZXRlIGluPwpgYGB7cn0Kc3VtbWVyID0gZmlsdGVyKG1hc3RlciwgU2Vhc29uID09ICJTdW1tZXIiKQpieV95ZWFyICA9IHN1bW1lciAlPiUKICBncm91cF9ieShZZWFyLCBOT0MsIGFkZCA9IFRSVUUpCmJ5X3llYXIgPSBieV95ZWFyICU+JSBzZWxlY3QoWWVhciwgTk9DKQpieV95ZWFyID0gdW5pcXVlKGJ5X3llYXIpCm51bV9zdW1tZXJvbHltcGljcyA9IHRhYmxlKGJ5X3llYXIkTk9DKQpudW1fc3VtbWVyb2x5bXBpY3MgPSBkYXRhLmZyYW1lKG51bV9zdW1tZXJvbHltcGljcykKbmFtZXMobnVtX3N1bW1lcm9seW1waWNzKSA8LSBjKCJOT0MiLCAiTnVtYmVyIikKI3NvcnRlZCBieSBudW1iZXIgb2Ygb2x5bXBpY3MgdGhleSBwYXJ0aWNpcGF0ZWQgaW4KbnVtc19zb3J0ZWQgPSBudW1fc3VtbWVyb2x5bXBpY3Nbb3JkZXIobnVtX3N1bW1lcm9seW1waWNzJE51bWJlciwgZGVjcmVhc2luZz1UKSxdCmRhdGF0YWJsZShudW1zX3NvcnRlZCkKYGBgCgoKCkhvdyBtYW55IG1lZGFscyBvZiBlYWNoIHR5cGUgZGlkIGVhY2ggY291bnRyeSB3aW4/CmBgYHtyfQpzdW1tZXJfbWVkYWwgPSBzdWJzZXQoc3VtbWVyLCBNZWRhbCAhPSAnTkEnKQpzdW1tZXJfbWVkYWwKYnlfbWVkYWwgID0gc3VtbWVyX21lZGFsICU+JQogIGdyb3VwX2J5KE1lZGFsLCBOT0MpCm51bV9tZWRhbCA9IHRhYmxlKGJ5X21lZGFsJE1lZGFsLCBieV9tZWRhbCROT0MpCm51bV9tZWRhbCA9IGRhdGEuZnJhbWUobnVtX21lZGFsKQpuYW1lcyhudW1fbWVkYWwpIDwtIGMoIk1lZGFsIiwgIk5PQyIsICJOdW1iZXIiKQoKI0V4dHJhY3RpbmcgbWVkYWwgZGF0YSBmb3IgMTAgY291bnRyaWVzCk5PQ3MgPSBjKCJVU0EiLCAiUlVTIiwgIkdFUiIsIkFVUyIsICJDSE4iLCAgIklORCIsICJDQU4iLCJOT1IiLCAiRklOIiwgIkFVVCIpCnN1bW1lcl90b3AgPSBzdWJzZXQobnVtX21lZGFsLCBOT0MgJWluJSBOT0NzKQpzdW1tZXJfdG9wCnN1bW1lcl90b3AkTWVkYWwgPC0gZmFjdG9yKHN1bW1lcl90b3AkTWVkYWwsbGV2ZWxzID0gYygnR29sZCcsICdTaWx2ZXInLCAnQnJvbnplJykpCgptZWRhbF9wbG90ID0gZ2dwbG90KHN1bW1lcl90b3AsIGFlcyh4PU5PQywgeT1OdW1iZXIsIGZpbGw9TWVkYWwsIG9yZGVyPU1lZGFsKSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpICsgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImdvbGQiLCAiZ3JleSIsICJicm93biIpKQoKbWVkYWxfcGxvdCArICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJVU0EiLCAiR0VSIiwiQVVTIiwgICJDSE4iLCJSVVMiLCJDQU4iLCJOT1IiLCAiRklOIiwgIklORCIsIkFVVCIpLCBsYWJlbHMgPSBjKCJVbml0ZWQgU3RhdGVzIiwgIkdlcm1hbnkiLCJBdXN0cmFsaWEiLCAgIkNoaW5hIiwiUnVzc2lhIiwiQ2FuYWRhIiwiTm9yd2F5IiwgIkZpbmxhbmQiLCAiSW5kaWEiLCJBdXN0cmlhIikpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgKyB4bGFiKCcnKSArIHlsYWIoJ1RvdGFsIE51bWJlciBvZiBNZWRhbHMnKSArIGNvb3JkX2ZsaXAoKSArIGdndGl0bGUoJ1RvdGFsIE1lZGFscyBhd2FyZGVkIGJ5IENvdW50cnkgQWNjcm9zcyBhbGwgU3VtbWVyIE9seW1waWNzJykKYGBgCgoKQnkgR2VuZGVyCgpgYGB7cn0KYnlfc2V4ICA9IHN1bW1lcl9tZWRhbCAlPiUKICBncm91cF9ieShTZXgsIE5PQykKbnVtX3NleCA9IHRhYmxlKGJ5X3NleCRTZXgsIGJ5X3NleCROT0MpCm51bV9zZXggPSBkYXRhLmZyYW1lKG51bV9zZXgpCm51bV9zZXgKbmFtZXMobnVtX3NleCkgPC0gYygiU2V4IiwgIk5PQyIsICJOdW1iZXIiKQpOT0NzID0gYygiVVNBIiwgICJHRVIiLCJBVVMiLCAgIkNITiIsIlJVUyIsIkNBTiIsIk5PUiIsICJGSU4iLCAiSU5EIiwiQVVUIikKbnVtX3NleF90b3AgPSBzdWJzZXQobnVtX3NleCwgTk9DICVpbiUgTk9DcykKbnVtX3NleF90b3AKbnVtX3NleF90b3AKc2V4X3Bsb3QgPSBnZ3Bsb3QobnVtX3NleF90b3AsIGFlcyh4PU5PQywgeT1OdW1iZXIsY29sb3VyPVNleCkpICsgZ2VvbV9wb2ludCgpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgKyBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1jKCJVU0EiLCAgIkdFUiIsIkFVUyIsICAiQ0hOIiwiUlVTIiwiQ0FOIiwiTk9SIiwgIkZJTiIsICJJTkQiLCJBVVQiKSwgbGFiZWxzID0gYygiVW5pdGVkIFN0YXRlcyIsICJHZXJtYW55IiwiQXVzdHJhbGlhIiwgICJDaGluYSIsIlJ1c3NpYSIsIkNhbmFkYSIsIk5vcndheSIsICJGaW5sYW5kIiwgIkluZGlhIiwiQXVzdHJpYSIpKSArIHhsYWIoJycpICsgeWxhYignVG90YWwgTnVtYmVyIG9mIE1lZGFscycpICsgY29vcmRfZmxpcCgpICsgZ2d0aXRsZSgnVG90YWwgTWVkYWxzIGF3YXJkZWQgYnkgQ291bnRyeSBhbmQgR2VuZGVyIEFjY3Jvc3MgYWxsIFN1bW1lciBPbHltcGljcycpCnNleF9wbG90CmBgYApPdmVyIFRpbWUKCgoKYGBge3J9Ck5PQ3MgPSBjKCdVU0EnLCAnUlVTJywgJ0FVUycsICdDSE4nKQoKbnVtX3llYXJfY29tcCA9IHRhYmxlKHN1bW1lcl9tZWRhbCRZZWFyLCBzdW1tZXJfbWVkYWwkTk9DKQpudW1feWVhcl9jb21wCm51bV95ZWFyX2NvbXAgPSBkYXRhLmZyYW1lKG51bV95ZWFyX2NvbXApCm51bV95ZWFyX2NvbXAKbmFtZXMobnVtX3llYXJfY29tcCkgPSBjKCJZZWFyIiwgIk5PQyIsICJOdW1iZXIiKQoKbnVtX3llYXJfY29tcApudW1feWVhcl9jb21wID0gc3Vic2V0KG51bV95ZWFyX2NvbXAsTk9DICVpbiUgTk9DcykKbnVtX3llYXJfY29tcApudW1feWVhcl9jb21wJFllYXIgPSBzdWJzdHJpbmcoYXMuRGF0ZShudW1feWVhcl9jb21wJFllYXIsIGZvcm1hdCA9ICIlWSIpLCAwLDQpCm51bV95ZWFyX2NvbXAKbnVtX3llYXJfY29tcCA9IHN1YnNldChudW1feWVhcl9jb21wLCBZZWFyID49IDE5ODQpCgp5ZWFyX3Bsb3QxID0gZ2dwbG90KG51bV95ZWFyX2NvbXAsIGFlcyh4PVllYXIsIHk9TnVtYmVyLCBncm91cCA9IE5PQywgY29sb3VyID0gTk9DKSkgKyBnZW9tX3BvaW50KCkgKyBnZW9tX2xpbmUoKQoKeWVhcl9wbG90MSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICAgKyB4bGFiKCcnKSArIHlsYWIoJ1RvdGFsIE51bWJlciBvZiBNZWRhbHMnKSAgKyBzY2FsZV9jb2xvdXJfZGlzY3JldGUoZ3VpZGUgPSBndWlkZV9sZWdlbmQocmV2ZXJzZT1UUlVFLCB0aXRsZT1OVUxMKSwgbGFiZWxzPWMoIkF1c3RyYWxpYSIsICJDaGluYSIsICJSdXNzaWEiLCAiVW5pdGVkIFN0YXRlcyIpKSArIGdndGl0bGUoJ1RvdGFsIE1lZGFscyBhd2FyZGVkIGJ5IENvdW50cnkgYW5kIFllYXInKQoKYGBgCiMjIyMgMi4gTWVkYWwgQ291bnRzIGFkanVzdGVkIGJ5IFBvcHVsYXRpb24sIEdEUAoKVGhlcmUgYXJlIGRpZmZlcmVudCB3YXlzIHRvIGNhbGN1bGF0ZSAic3VjY2VzcyIuIENvbnNpZGVyIHRoZSBmb2xsb3dpbmcgdmFyaWFudHMgYW5kIGNob29zZSBvbmUgKGFuZCBtYWtlIHN1cmUgeW91ciBjaG9pY2UgaXMgY2xlYXIgaW4gdGhlIHZpc3VhbGl6YXRpb24pOiAgCiAgLSBKdXN0IGNvbnNpZGVyIGdvbGQgbWVkYWxzLiAgCiAgLSBTaW1wbHkgYWRkIHVwIHRoZSBudW1iZXIgb2YgbWVkYWxzIG9mIGRpZmZlcmVudCB0eXBlcy4gICAgCiAgLSBDcmVhdGUgYW4gaW5kZXggaW4gd2hpY2ggbWVkYWxzIGFyZSB2YWx1ZWQgZGlmZmVyZW50bHkuIChnb2xkPTMsIHNpbHZlcj0yLCBicm9uemU9MSkuICAgCiAgLSBBIHJlYXNvbmFibGUgb3RoZXIgd2F5IHRoYXQgeW91IHByZWZlci4KICAKTm93LCBhZGp1c3QgdGhlIHJhbmtpbmcgb2YgbWVkYWwgc3VjY2VzcyBieSAoYSkgR0RQIHBlciBjYXBpdGEgYW5kIChiKSBwb3B1bGF0aW9uLiBZb3UgaGF2ZSBub3cgdGhyZWUgcmFua2luZ3M6IHVuYWRqdXN0ZWQgcmFua2luZywgYWRqdXN0ZWQgYnkgR0RQIHBlciBjYXBpdGEsIGFuZCBhZGp1c3RlZCBieSBwb3B1bGF0aW9uLgoKVmlzdWFsaXplIGhvdyB0aGVzZSByYW5raW5ncyBkaWZmZXIuIEZlZWwgZnJlZSB0byBoaWdobGlnaHQgYSBzcGVjaWZpYyBwYXR0ZXJuIChlLmcuICJTb3V0aCBLb3JlYSAtLSBzcGVjaWFsaXphdGlvbiByZWFwcyBiZW5lZml0cyIgb3IgIlRoZSBzdXBlcnBvd2VycyBsb3NpbmcgdGhlaXIgZ3JpcCIpLgoKYGBge3J9Cm51bV95ZWFyX2NvbXAgPSB0YWJsZShzdW1tZXJfbWVkYWwkWWVhciwgc3VtbWVyX21lZGFsJE1lZGFsLCBzdW1tZXJfbWVkYWwkTk9DKQpudW1feWVhcl9jb21wID0gZGF0YS5mcmFtZShudW1feWVhcl9jb21wKQpuYW1lcyhudW1feWVhcl9jb21wKSA9IGMoIlllYXIiLCAiTWVkYWwiLCAiTk9DIiwgIk51bWJlciIpCk5PQ3MgPSBjKCJVU0EiLCAgIkdFUiIsIkFVUyIsICAiQ0hOIiwiUlVTIiwiQ0FOIiwiTk9SIiwgIkZJTiIsICJJTkQiLCJBVVQiKQpnb2xkX2NvbXAgPSAgc3Vic2V0KG51bV95ZWFyX2NvbXAsTWVkYWwgPT0gJ0dvbGQnKQpnb2xkX2NvbXAgPSAgc3Vic2V0KGdvbGRfY29tcCxOT0MgJWluJSBOT0NzKQpnb2xkX3Bsb3QgPSBnZ3Bsb3QoZ29sZF9jb21wLCBhZXMoeD1OT0MsIHk9TnVtYmVyKSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScsIGZpbGwgPSAnZ29sZCcpCm51bV95ZWFyX2NvbXAgICAgICAgICAgICAgICAgICAKZ29sZF9wbG90ICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgKyAgIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWMoIlVTQSIsICAiR0VSIiwiQVVTIiwgICJDSE4iLCJSVVMiLCJDQU4iLCJOT1IiLCAiRklOIiwgIklORCIsIkFVVCIpLCBsYWJlbHMgPSBjKCJVbml0ZWQgU3RhdGVzIiwgIkdlcm1hbnkiLCJBdXN0cmFsaWEiLCAgIkNoaW5hIiwiUnVzc2lhIiwiQ2FuYWRhIiwiTm9yd2F5IiwgIkZpbmxhbmQiLCAiSW5kaWEiLCJBdXN0cmlhIikpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgKyB4bGFiKCcnKSArIHlsYWIoJ1RvdGFsIE51bWJlciBvZiBHb2xkIE1lZGFscycpICsgZ2d0aXRsZSgnVG90YWwgR29sZCBNZWRhbHMgYXdhcmRlZCBieSBDb3VudHJ5IEFjY3Jvc3MgYWxsIFN1bW1lciBPbHltcGljcycpCmBgYAoKYGBge3J9CnN1bW1lcl9tZWRhbF9nb2xkID0gc3Vic2V0KHN1bW1lcl9tZWRhbCwgTWVkYWwgPT0gJ0dvbGQnKQpnb2xkX2NvbXAxIDwtIHVuaXF1ZShkYXRhLmZyYW1lKHN1bW1lcl9tZWRhbF9nb2xkJE5PQywgc3VtbWVyX21lZGFsX2dvbGQkUG9wdWxhdGlvbi54KSkKbmFtZXMoZ29sZF9jb21wMSkgPSBjKCJOT0MiLCAiUG9wdWxhdGlvbiIpCgpnb2xkX2NvbXAyIDwtIHRhYmxlKHN1bW1lcl9tZWRhbCROT0MsIHN1bW1lcl9tZWRhbCRNZWRhbCkKZ29sZF9jb21wMiA9IGRhdGEuZnJhbWUoZ29sZF9jb21wMikKbmFtZXMoZ29sZF9jb21wMikgPSBjKCJOT0MiLCAiTWVkYWwiLCAiTnVtYmVyIikKZ29sZF9jb21wMj0gc3Vic2V0KGdvbGRfY29tcDIsIE1lZGFsID09ICdHb2xkJykKZ29sZF9jb21wMQpnb2xkX2NvbXAgPSBtZXJnZShnb2xkX2NvbXAxLCBnb2xkX2NvbXAyLCBieSA9ICdOT0MnKQoKZ29sZF9jb21wIDwtIHRyYW5zZm9ybShnb2xkX2NvbXAsIEdvbGRCeVBvcHVsYXRpb24gPSBOdW1iZXIqMTAwMDAwMC8oUG9wdWxhdGlvbikpCmdvbGRfY29tcCA9IHN1YnNldChnb2xkX2NvbXAsIEdvbGRCeVBvcHVsYXRpb24gIT0gSW5mKQpnb2xkX2NvbXAgPSBnb2xkX2NvbXBbb3JkZXIoZ29sZF9jb21wJEdvbGRCeVBvcHVsYXRpb24sIGRlY3JlYXNpbmc9VCksXQpnb2xkX2NvbXAzIDwtIHVuaXF1ZShkYXRhLmZyYW1lKHN1bW1lcl9tZWRhbF9nb2xkJE5PQywgc3VtbWVyX21lZGFsX2dvbGQkcmVnaW9uKSkKZ29sZF9jb21wMyROT0MgPSBnb2xkX2NvbXAzJHN1bW1lcl9tZWRhbF9nb2xkLk5PQwoKZ29sZF9jb21wID0gbWVyZ2UoZ29sZF9jb21wLCBnb2xkX2NvbXAzLCBieSA9ICdOT0MnKQpnb2xkX2NvbXAkQ291bnRyeSA8LSBnb2xkX2NvbXAkc3VtbWVyX21lZGFsX2dvbGQucmVnaW9uCgpnb2xkX2NvbXAgPSBnb2xkX2NvbXBbb3JkZXIoZ29sZF9jb21wJEdvbGRCeVBvcHVsYXRpb24sIGRlY3JlYXNpbmc9VCksXQpnb2xkX3BvcCA9IGRhdGEuZnJhbWUoZ29sZF9jb21wJENvdW50cnksIGdvbGRfY29tcCRHb2xkQnlQb3B1bGF0aW9uKQpnb2xkX3BvcCA9IGdvbGRfcG9wWzA6MTUsXQpnb2xkX3BvcCRDb3VudHJ5ID0gZ29sZF9wb3AkZ29sZF9jb21wLkNvdW50cnkKZ29sZF9wb3AkR29sZEJ5UG9wdWxhdGlvbiA9IGdvbGRfcG9wJGdvbGRfY29tcC5Hb2xkQnlQb3B1bGF0aW9uCmdvbGRfcG9wX3Bsb3QgPSBnZ3Bsb3QoZ29sZF9wb3AsIGFlcyh4PUNvdW50cnksIHk9R29sZEJ5UG9wdWxhdGlvbikpICsgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBmaWxsID0gJ2dvbGQnKQpnb2xkX3BvcF9wbG90ICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSwgYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChzaXplPTcuNSkpICsgICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1nb2xkX3BvcCRDb3VudHJ5KSArIHhsYWIoJycpICsgeWxhYignTm8uIG9mIEdvbGQgTWVkYWxzIGJ5IFBvcHVsYXRpb24gaW4gTWlsbGlvbnMnKSArIGdndGl0bGUoJ0dvbGQgTWVkYWxzIHRvIFBvcHVsYXRpb24gUmF0aW8gZm9yIENvdW50cmllcyBhY2Nyb3NzIGFsbCBTdW1tZXIgb2x5bXBpY3MnKQpgYGAKYGBge3J9Cgpnb2xkX2NvbXAxIDwtIHVuaXF1ZShkYXRhLmZyYW1lKHN1bW1lcl9tZWRhbF9nb2xkJE5PQywgc3VtbWVyX21lZGFsX2dvbGQkR0RQLnBlci5DYXBpdGEueCkpCm5hbWVzKGdvbGRfY29tcDEpID0gYygiTk9DIiwgIkdEUCIpCgpnb2xkX2NvbXAgPSBtZXJnZShnb2xkX2NvbXAxLCBnb2xkX2NvbXAyLCBieSA9ICdOT0MnKQpnb2xkX2NvbXAKZ29sZF9jb21wIDwtIHRyYW5zZm9ybShnb2xkX2NvbXAsIEdvbGRCeUdEUCA9IE51bWJlcioxMDAwLyhHRFApKQpnb2xkX2NvbXAgPSBzdWJzZXQoZ29sZF9jb21wLCBHb2xkQnlHRFAgIT0gSW5mKQpnb2xkX2NvbXAKZ29sZF9jb21wID0gZ29sZF9jb21wW29yZGVyKGdvbGRfY29tcCRHb2xkQnlHRFAsIGRlY3JlYXNpbmc9VCksXQpnb2xkX2NvbXAzIDwtIHVuaXF1ZShkYXRhLmZyYW1lKHN1bW1lcl9tZWRhbF9nb2xkJE5PQywgc3VtbWVyX21lZGFsX2dvbGQkcmVnaW9uKSkKZ29sZF9jb21wMyROT0MgPSBnb2xkX2NvbXAzJHN1bW1lcl9tZWRhbF9nb2xkLk5PQwpnb2xkX2NvbXAzJENvdW50cnkgPSBnb2xkX2NvbXAzJHN1bW1lcl9tZWRhbF9nb2xkLnJlZ2lvbgoKZ29sZF9jb21wID0gbWVyZ2UoZ29sZF9jb21wLCBnb2xkX2NvbXAzLCBieSA9ICdOT0MnKQpnb2xkX2NvbXAkQ291bnRyeSA8LSBnb2xkX2NvbXAkc3VtbWVyX21lZGFsX2dvbGQKZ29sZF9jb21wID0gc3Vic2V0KGdvbGRfY29tcCwgTk9DICE9ICdVUlMnKQpnb2xkX2NvbXAgPSBzdWJzZXQoZ29sZF9jb21wLCBOT0MgIT0gJ1lVRycpCgpnb2xkX2NvbXAgPSBnb2xkX2NvbXBbb3JkZXIoZ29sZF9jb21wJEdvbGRCeUdEUCwgZGVjcmVhc2luZz1UKSxdCmdvbGRfY29tcCRDb3VudHJ5ID0gZ29sZF9jb21wJHN1bW1lcl9tZWRhbF9nb2xkLnJlZ2lvbgpnb2xkX3BvcCA9IGRhdGEuZnJhbWUoZ29sZF9jb21wJENvdW50cnksIGdvbGRfY29tcCRHb2xkQnlHRFApCmdvbGRfcG9wID0gZ29sZF9wb3BbMDo5LF0KZ29sZF9wb3AkQ291bnRyeSA9IGdvbGRfcG9wJGdvbGRfY29tcC5Db3VudHJ5CmdvbGRfcG9wJEdvbGRCeUdEUCA9IGdvbGRfcG9wJGdvbGRfY29tcC5Hb2xkQnlHRFAKZ29sZF9wb3BfcGxvdCA9IGdncGxvdChnb2xkX3BvcCwgYWVzKHg9Q291bnRyeSwgeT1Hb2xkQnlHRFApKSArIGdlb21fYmFyKHN0YXQ9J2lkZW50aXR5JywgZmlsbCA9ICdnb2xkJykKZ29sZF9wb3BfcGxvdCArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpICsgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpLCBheGlzLnRpdGxlLnk9ZWxlbWVudF90ZXh0KHNpemU9Ny41KSkgKyAgIHNjYWxlX3hfZGlzY3JldGUobGltaXRzPWdvbGRfcG9wJENvdW50cnkpICsgeGxhYignJykgKyB5bGFiKCcgTm8uIG9mIEdvbGQgTWVkYWxzL0dEUCBQZXIgQ2FwaXRhKFRob3VzYW5kcyknKSArIGdndGl0bGUoJ0dvbGQgTWVkYWxzIHRvIEdEUCBQZXIgQ2FwaXRhIFJhdGlvIGZvciBDb3VudHJpZXMgYWNjcm9zcyBhbGwgU3VtbWVyIG9seW1waWNzJykKYGBgCgoKCiMjIyMgMy4gSG9zdCBDb3VudHJ5IEFkdmFudGFnZQoKVW50aWwgdGhlIDIwMTYgUmlvIFN1bW1lciBPbHltcGljcyAob3VyIGRhdGEgZW5kcyBoZXJlKSwgdGhlcmUgd2VyZSAyMyBob3N0IGNpdGllcy4gQ2FsY3VsYXRlIHdoZXRoZXIgdGhlIGhvc3QgbmF0aW9uIGhhZCBhbiBhZHZhbnRhZ2UuIFRoYXQgaXMgY2FsY3VsYXRlIHdoZXRoZXIgdGhlIGhvc3QgY291bnRyeSBkaWQgd2luIG1vcmUgbWVkYWxzIHdoZW4gdGhlIFN1bW1lciBPbHltcGljcyB3YXMgaW4gdGhlaXIgY291bnRyeSBjb21wYXJlZCB0byBvdGhlciB0aW1lcy4gCgpOb3RlLCB0aGF0IHRoZSAyMyBob3N0IGNpdGllcyBhcmUgbm90ZWQgaW4gdGhlIGRhdGEgYnV0IG5vdCAgdGhlIGNvdW50cmllcyB0aGV5IGFyZSBsb2NhdGVkIGluLiBUaGlzIGhhcHBlbnMgY29tbW9ubHkgYW5kIG9mdGVuIFdpa2lwZWRpYSBoYXMgdGhlIFtraW5kIG9mIGFkZGl0aW9uYWwgZGF0YSB5b3Ugd2FudCBmb3IgdGhlIHRhc2tdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N1bW1lcl9PbHltcGljX0dhbWVzKS4gVG8gc2F2ZSB5b3Ugc29tZSB0aW1lLCBoZXJlIGlzIGEgcXVpY2sgd2F5IHRvIGdldCB0aGlzIGtpbmQgb2YgdGFibGUgZnJvbSBXaWtpcGVkaWEgaW50byBSOgoKUHJvdmlkZSBhIHZpc3VhbGl6YXRpb24gb2YgdGhlIGhvc3QgY291bnRyeSBhZHZhbnRhZ2UgKG9yIGFic2VuY2UgdGhlcmVvZikuCgpgYGB7cn0KY291bnRyaWVzIDwtIGMoIkdyZWVjZSIsICJGcmFuY2UiLCAiVW5pdGVkIFN0YXRlcyIsICJVbml0ZWQgS2luZ2RvbSIsICAiU3dlZGVuIiwgICJCZWxnaXVtIiwgIkZyYW5jZSIsICAiTmV0aGVybGFuZHMiLCAiVW5pdGVkIFN0YXRlcyIsICJHZXJtYW55IiwgICJVbml0ZWQgS2luZ2RvbSIsICAiRmlubGFuZCIsICJBdXN0cmFsaWEiLCAiSXRhbHkiLCAiSmFwYW4iLCAiTWV4aWNvIiwgICJXZXN0IEdlcm1hbnkiLCAiQ2FuYWRhIiwgIlNvdmlldCBVbmlvbiIsICJVbml0ZWQgU3RhdGVzIiwiU291dGggS29yZWEiLCAiU3BhaW4iLCAiVW5pdGVkIFN0YXRlcyIsICJBdXN0cmFsaWEiLCAiR3JlZWNlIiAgICwiQ2hpbmEiLCJVbml0ZWQgS2luZ2RvbSIsICAiQnJhemlsIikKCmhvc3RfTk9DcyA8LSBjKCJGUkciLCAiRlJBIiwgIlVTQSIsICJHQlIiLCAgIlNXRSIsICAiQkVMIiwgIkZSQSIsICAiTkVEIiwgIlVTQSIsICJGUkciLCAgIkdCUiIsICAiRklOIiwgIkFVUyIsICJJVEEiLCAiSlBOIiwgIk1FWCIsICAiRlJHIiwgIkNBTiIsICJVUlMiLCAiVVNBIiwiS09SIiwgIkVTUCIsICJVU0EiLCAiQVVTIiwgIkdSRSIgICAsIkNITiIsIkdCUiIsICAiQlJBIikKCnN1bW1lcl9tZWRhbCA9IHN1YnNldChzdW1tZXJfbWVkYWwsIFllYXIgIT0gMTkwNikKZ29sZCA9IHN1YnNldChzdW1tZXJfbWVkYWwsIE1lZGFsID09ICdHb2xkJykKZ29sZF95ZWFyID0gdGFibGUoZ29sZCROT0MsIGdvbGQkWWVhcikKZ29sZF95ZWFyID0gZGF0YS5mcmFtZShnb2xkX3llYXIpCm5hbWVzKGdvbGRfeWVhcikgPSBjKCdOT0MnLCAnWWVhcicsICdOdW1iZXInKQp5ZWFycz0gYXMuZmFjdG9yKHVuaXF1ZShnb2xkJFllYXIpKQp5ZWFycyA9IHNvcnQodW5pcXVlKHllYXJzKSkKeWVhcnMKaG9zdHMgPSBkYXRhLmZyYW1lKHNvcnQodW5pcXVlKHllYXJzKSksIGMoIkdyZWVjZSIsICJGcmFuY2UiLCAiVW5pdGVkIFN0YXRlcyIsICJVbml0ZWQgS2luZ2RvbSIsICAiU3dlZGVuIiwgICJCZWxnaXVtIiwgIkZyYW5jZSIsICAiTmV0aGVybGFuZHMiLCAiVW5pdGVkIFN0YXRlcyIsICJHZXJtYW55IiwgICJVbml0ZWQgS2luZ2RvbSIsICAiRmlubGFuZCIsICJBdXN0cmFsaWEiLCAiSXRhbHkiLCAiSmFwYW4iLCAiTWV4aWNvIiwgICJXZXN0IEdlcm1hbnkiLCAiQ2FuYWRhIiwgIlNvdmlldCBVbmlvbiIsICJVbml0ZWQgU3RhdGVzIiwiU291dGggS29yZWEiLCAiU3BhaW4iLCAiVW5pdGVkIFN0YXRlcyIsICJBdXN0cmFsaWEiLCAiR3JlZWNlIiAgICwiQ2hpbmEiLCJVbml0ZWQgS2luZ2RvbSIsICAiQnJhemlsIikpCiAgICAKCm51bV95ZWFyX2NvbXAgPSB0YWJsZShnb2xkJFllYXIsIGdvbGQkTk9DKQpudW1feWVhcl9jb21wID0gZGF0YS5mcmFtZShudW1feWVhcl9jb21wKQpuYW1lcyhudW1feWVhcl9jb21wKSA9IGMoIlllYXIiLCAiTk9DIiwgIk51bWJlciIpCm51bV95ZWFyX2NvbXAgPSBzdWJzZXQobnVtX3llYXJfY29tcCwgTk9DICVpbiUgYygiRlJHIiwgIkZSQSIsICJVU0EiLCAiR0JSIiwgICJTV0UiLCAgIkJFTCIsICJGUkEiLCAgIk5FRCIsICJVU0EiLCAiRlJHIiwgICJHQlIiLCAgIkZJTiIsICJBVVMiLCAiSVRBIiwgIkpQTiIsICJNRVgiLCAgIkZSRyIsICJDQU4iLCAiVVJTIiwgIlVTQSIsIktPUiIsICJFU1AiLCAiVVNBIiwgIkFVUyIsICJHUkUiICAgLCJDSE4iLCJHQlIiLCAgIkJSQSIpKQoKb2x5bXBpY19ob3N0cyA8LSBmdW5jdGlvbigpewogIAogIGhvc3Rfcm93MSA9IHN1YnNldChudW1feWVhcl9jb21wLCBZZWFyID09IHllYXJzWzBdKQogIGhvc3Rfcm93MSA9IHN1YnNldChob3N0X3JvdzEsIE5PQyA9PSBob3N0X05PQ3NbMF0pCiAgZm9yIChpIGluIDE6MjkpIHsKICAgIAogICAgeWVhciA8LSB5ZWFyc1tpXQogICAgTk9DMSA8LSBob3N0X05PQ3NbaV0KICAgIGhvc3Rfcm93MiA9IHN1YnNldChudW1feWVhcl9jb21wLCBZZWFyID09IHllYXIpCiAgICBob3N0X3JvdzIgPSBzdWJzZXQoaG9zdF9yb3cyLCBOT0MgPT0gTk9DMSkKICAgIGhvc3Rfcm93MSA9IHJiaW5kKGhvc3Rfcm93MSwgaG9zdF9yb3cyKQogIH0KICByZXR1cm4oaG9zdF9yb3cxKQp9CgphdmVyYWdlX2dvbGRzIDwtIGZ1bmN0aW9uKCl7CiAgYXZlcmFnZXMgPSBjKCkKICBob3N0X3JvdzEgPSBzdWJzZXQobnVtX3llYXJfY29tcCwgTk9DID09IGhvc3RfTk9Dc1swXSkKICBhdmVyYWdlID0gbWVhbihob3N0X3JvdzEkTnVtYmVyKQogIGF2ZXJhZ2VzID0gYXBwZW5kKGF2ZXJhZ2VzLCBhdmVyYWdlKQogIGZvciAoaSBpbiAxOjI5KSB7CiAgICBOT0MxIDwtIGhvc3RfTk9Dc1tpXQogICAgaG9zdF9yb3cyID0gc3Vic2V0KG51bV95ZWFyX2NvbXAsIE5PQyA9PSBOT0MxKQogICAgYXZlcmFnZSA9IG1lYW4oaG9zdF9yb3cyJE51bWJlcikKICAgIGF2ZXJhZ2VzID0gYXBwZW5kKGF2ZXJhZ2VzLCBhdmVyYWdlKQogIH0KICByZXR1cm4oYXZlcmFnZXMpCiAgfQpob3N0cyA9IG9seW1waWNfaG9zdHMoKQpob3N0cwphdmVyYWdlcyA9IGF2ZXJhZ2VfZ29sZHMoKQpsZW5ndGgoYXZlcmFnZXMpCmF2ZXJhZ2VzID0gYXZlcmFnZXNbLSgwOjEpXQphdmVyYWdlcwphdmVyYWdlcyA9IGF2ZXJhZ2VzWy1sZW5ndGgoYXZlcmFnZXMpXQphdmVyYWdlcwpob3N0cyRhdmVyYWdlX292ZXJfeWVhcnMgPSBhdmVyYWdlcwpob3N0cwpsaWJyYXJ5KGdncGxvdDIpCmdvbGRfaG9zdCA9IGdncGxvdChob3N0cywgYWVzKHg9Tk9DKSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScsIGZpbGwgPSAnZ29sZCcsIGFlcyh5PU51bWJlcikpICsgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLCBmaWxsID0gJ3JlZCcsIGFlcyh5PWF2ZXJhZ2Vfb3Zlcl95ZWFycykpICsgc2NhbGVfeF9kaXNjcmV0ZSggbGFiZWxzID0gYygiR3JlZWNlOiAxODk2IiwgIkZyYW5jZTogMTkwMCIsICJVbml0ZWQgU3RhdGVzOiAxOTA0IiwgIlVuaXRlZCBLaW5nZG9tOiAxOTA4IiwgICJTd2VkZW46IDE5MTIiLCAgIkJlbGdpdW06IDE5MjAiLCAiRnJhbmNlOiAxOTI0IiwgICJOZXRoZXJsYW5kczogMTkyOCIsICJVbml0ZWQgU3RhdGVzOiAxOTMyIiwgIkdlcm1hbnk6IDE5MzYiLCAgIlVuaXRlZCBLaW5nZG9tOiAxOTQ4IiwgICJGaW5sYW5kOiAxOTUyIiwgIkF1c3RyYWxpYTogMTk1NiIsICJJdGFseTogMTk2MCIsICJKYXBhbjogMTk2NCIsICJNZXhpY286IDE5NjgiLCAgIldlc3QgR2VybWFueTogMTk3MiIsICJDYW5hZGE6IDE5NzYiLCAiU292aWV0IFVuaW9uOiAxOTgwIiwgIlVuaXRlZCBTdGF0ZXM6IDE5ODQiLCJTb3V0aCBLb3JlYTogMTk4OCIsICJTcGFpbjogMTk5MiIsICJVbml0ZWQgU3RhdGVzOiAxOTk2IiwgIkF1c3RyYWxpYTogMjAwMCIsICJHcmVlY2U6IDIwMDQiICAgLCJDaGluYTogMjAwOCIsIlVuaXRlZCBLaW5nZG9tOiAyMDEyIiwgICJCcmF6aWw6IDIwMTYiKSkgKyB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSArIHhsYWIoJycpICsgeWxhYignVG90YWwgTnVtYmVyIG9mIEdvbGQgTWVkYWxzIHdvbiBieSBIb3N0JykKZ29sZF9ob3N0ICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSkgKwpnZ3RpdGxlKCdIb3N0IENvdW50cnkgQWR2YW50YWdlIEFjY3Jvc3MgYWxsIFN1bW1lciBPbHltcGljcycpCmBgYAoKTm90ZTogUmVkIGRlbm90ZXMgdGhlIGF2ZXJhZ2UgbWVkYWxzIGVhcm5lZCBieSB0aGUgaG9zdCBjb3VudHJ5IGFjY3Jvc3MgYWxsIFN1bW1lciBPbHltcGljcy4gWWVsbG93IGRlbm90ZXMgdGhlIG51bWJlciBvZiBtZWRhbHMgZWFybmVkIGJ5IHRoZSBob3N0IGNvdW50cnkgaW4gdGhlIE9seW1waWNzIGhvc3RlZCBieSB0aGUgY291bnRyeS4KCgoKIyMjIyA0LiBNb3N0IHN1Y2Nlc3NmdWwgYXRobGV0ZXMKCmEpIE5vdywgbGV0J3MgbG9vayBhdCB0aGUgbW9zdCBzdWNjZXNzZnVsIGF0aGxldGVzLiBQcm92aWRlIGEgdmlzdWFsIGRpc3BsYXkgb2YgdGhlIG1vc3Qgc3VjY2Vzc2Z1bCBhdGhsZXRlcyBvZiBhbGwgdGltZS4KCmBgYHtyfQpieV9hdGhsZXRlcyAgPSBzdW1tZXJfbWVkYWwgJT4lCiAgZ3JvdXBfYnkoTmFtZSwgTWVkYWwsIHJlZ2lvbikKYnlfYXRobGV0ZXMgPSB1bmlxdWUoYnlfYXRobGV0ZXMpCmJ5X2F0aGxldGVzJENvdW50cnkgPSBieV9hdGhsZXRlcyRyZWdpb24KbnVtX2F0aGxldGVzID0gdGFibGUoYnlfYXRobGV0ZXMkTmFtZSwgYnlfYXRobGV0ZXMkQ291bnRyeSkKbnVtX2F0aGxldGVzID0gZGF0YS5mcmFtZShudW1fYXRobGV0ZXMpCm5hbWVzKG51bV9hdGhsZXRlcykgPC0gYygiTmFtZSIsICdDb3VudHJ5JywgIk51bWJlciIpCiNzb3J0ZWQgYnkgbnVtYmVyIG9mIG1lZGFscwpudW1zX3NvcnRlZCA9IG51bV9hdGhsZXRlc1tvcmRlcihudW1fYXRobGV0ZXMkTnVtYmVyLCBkZWNyZWFzaW5nPVQpLF0KbnVtc19zb3J0ZWQgPSBzdWJzZXQobnVtc19zb3J0ZWQsIE51bWJlciAhPSAwKQoKbnVtc19zb3J0ZWQxID0gbnVtc19zb3J0ZWRbMDozMCxdCm51bXNfc29ydGVkMQphdGhsZXRlc19wbG90ID0gZ2dwbG90KG51bXNfc29ydGVkMSwgYWVzKHg9cmVvcmRlcihOYW1lLCAtTnVtYmVyLCByZXZlcnNlID1UUlVFKSwgeT1OdW1iZXIsIGZpbGwgPSBDb3VudHJ5KSkgKyBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpKyB4bGFiKCcnKSArIHlsYWIoJ051bWJlciBvZiBNZWRhbHMnKQphdGhsZXRlc19wbG90ICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgKyBjb29yZF9mbGlwKCkgKyBnZ3RpdGxlKCdNb3N0IE1lZGFscyB3b24gYWNjcm9zcyBhbGwgU3VtbWVyIE9seW1waWNzLCBieSBDb3VudHJ5KFRvcCAzMCknKQpgYGAKCgpiKSBDaG9vc2Ugb25lIG9yIHR3byBhZGRpdGlvbmFsIGRpbWVuc2lvbnMgYW1vbmcgZ2VuZGVyLCBoZWlnaHQsIHdlaWdodCwgc3BvcnQsIGRpc2NpcGxpbmUsIGV2ZW50LCB5ZWFyLCBhbmQgY291bnRyeSB0byBoaWdobGlnaHQgYW4gaW50ZXJlc3RpbmcgcGF0dGVybiBpbiB0aGUgZGF0YS4KYGBge3J9CmJ5X2F0aGxldGVzICA9IHN1bW1lcl9tZWRhbCAlPiUKICBncm91cF9ieShOYW1lLCBNZWRhbCwgWWVhciwgU2V4KQpieV9hdGhsZXRlcyA9IHVuaXF1ZShieV9hdGhsZXRlcykKbnVtX2F0aGxldGVzID0gdGFibGUoYnlfYXRobGV0ZXMkTmFtZSwgYnlfYXRobGV0ZXMkWWVhcixieV9hdGhsZXRlcyRTZXgpCm51bV9hdGhsZXRlcyA9IGRhdGEuZnJhbWUobnVtX2F0aGxldGVzKQoKbmFtZXMobnVtX2F0aGxldGVzKSA8LSBjKCJOYW1lIiwgJ1llYXInLCJTZXgiLCAiTnVtYmVyIikKbnVtc19zb3J0ZWQgPSBzdWJzZXQobnVtc19zb3J0ZWQsIE51bWJlciAhPSAwKQojc29ydGVkIGJ5IG51bWJlciBvZiBtZWRhbHMKbnVtc19zb3J0ZWQgPSBudW1fYXRobGV0ZXNbb3JkZXIobnVtX2F0aGxldGVzJE51bWJlciwgZGVjcmVhc2luZz1UKSxdCm51bXNfc29ydGVkMSA9IG51bXNfc29ydGVkWzA6MzAsXQpudW1zX3NvcnRlZDEkWWVhciA9IHN1YnN0cmluZyhhcy5EYXRlKG51bXNfc29ydGVkMSRZZWFyLCBmb3JtYXQgPSAiJVkiKSwgMCw0KQpudW1zX3NvcnRlZDEkTmFtZVllYXIgPC0gcGFzdGUobnVtc19zb3J0ZWQxJE5hbWUsbnVtc19zb3J0ZWQxJFllYXIpCmF0aGxldGVzX3Bsb3QgPSBnZ3Bsb3QobnVtc19zb3J0ZWQxLCBhZXMoeD1yZW9yZGVyKE5hbWVZZWFyLCAtTnVtYmVyKSwgeT1OdW1iZXIsIGZpbGwgPSBTZXgpKSArIGdlb21fYmFyKHN0YXQ9J2lkZW50aXR5JykgKyB4bGFiKCcnKSArIHlsYWIoJ051bWJlciBvZiBNZWRhbHMgd29uIGluIGEgc2luZ2xlIHllYXI6IFRvcCAzMCcpCgphdGhsZXRlc19wbG90ICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSkgKyBnZ3RpdGxlKCdIaWdoZXN0IG51bWJlciBvZiBtZWRhbHMgd29uIGluIGEgc2luZ2xlIE9seW1waWNzIGJ5IEdlbmRlciAoVG9wIDMwKScpCmBgYAoKIyMjIyA1LiBNYWtlIHR3byBwbG90cyBpbnRlcmFjdGl2ZQoKQ2hvb3NlIDIgb2YgdGhlIHBsb3RzIHlvdSBjcmVhdGVkIGFib3ZlIGFuZCBhZGQgaW50ZXJhY3Rpdml0eS4gQnJpZWZseSBkZXNjcmliZSB0byB0aGUgZWRpdG9yIHdoeSBpbnRlcmFjdGl2aXR5IGluIHRoZXNlIHZpc3VhbGl6YXRpb24gaXMgcGFydGljdWxhcmx5IGhlbHBmdWwgZm9yIGEgcmVhZGVyLgoKMSkgTnVtYmVyIG9mIE1lZGFscyBieSBIZWlnaHQgYW5kIFdlaWdodDogQ2F0ZWdvcml6ZWQgYnkgYXRobGV0ZXMgd2hvIGhhdmUgd29uIG1lZGFscyB2cy4gdGhvc2UgdGhhdCBkaWQgbm90LiBUaGUgcGxvdCBhbGxvd3MgZm9yIGhlaWdodCBhbmQgd2VpZ2h0IGNvbXBhcmlzb25zIGFuZCBzaG93cyB0aGF0IGF0aGxldGVzIHRoYXQgYXJlIG91dGxpZXJzIGFyZSBtb3JlIGxpa2VseSB0byB3aW4uIFRoaXMgc2hvd3MgdGhhdCBwaHlzaWNhbCBjaGFyYWN0ZXJpc3RpY3MgcGxheSBhIGtleSByb2xlIGluIHRoZSBjb21wZXRpdGlvbi4gSW50ZXJhY3Rpdml0eSBhbGxvd3MgZm9yIG51bWVyaWNhbCBpbmZvcm1hdGlvbiBvbiB0aGUgY2hhcnQgc2luY2UgaXQgaXMgaGFyZCB0byByZWFkLgoyKSBJbnRlcmFjdGl2aXR5IGFkZGVkIHRvIHRoZSBlYXJsaWVyIHBsb3Qgb2YgTnVtYmVyIG9mIG1lZGFscyBhd2FyZGVkIGJ5IGdlbmRlciBpbiB0aGUgdG9wIGVsZXZlbiBjb3VudHJpZXMuIEludGVyYWN0aXZpdHkgYWxsb3dzIHRoZSByZWFkZXIgdG8gc2VlIHRoZSBleGFjdCBudW1iZXJzIGFuZCBoZW5jZSBtYWtlIG51bWVyaWNhbCBjb21wYXJpc29ucy4KYGBge3J9CnN1bW1lcl9tZWRhbCRDb3VudHJ5ID0gc3VtbWVyX21lZGFsJHJlZ2lvbgpieV9hdGhsZXRlcyAgPSBzdW1tZXJfbWVkYWwgJT4lCiAgZ3JvdXBfYnkoTmFtZSwgTWVkYWwsIFllYXIsIENvdW50cnksIFNleCkKYnlfYXRobGV0ZXMgPSB1bmlxdWUoYnlfYXRobGV0ZXMpCm51bV9hdGhsZXRlcyA9IHRhYmxlKGJ5X2F0aGxldGVzJE5hbWUsIGJ5X2F0aGxldGVzJFllYXIpCm51bV9hdGhsZXRlcyA9IGRhdGEuZnJhbWUobnVtX2F0aGxldGVzKQpuYW1lcyhudW1fYXRobGV0ZXMpIDwtIGMoIk5hbWUiLCAnWWVhcicsIk51bWJlciIpClNleF9Db3VudHJ5ID0gdW5pcXVlKGRhdGEuZnJhbWUoc3VtbWVyX21lZGFsJE5hbWUsc3VtbWVyX21lZGFsJFNleCwgc3VtbWVyX21lZGFsJENvdW50cnksIHN1bW1lcl9tZWRhbCRIZWlnaHQsIHN1bW1lcl9tZWRhbCRXZWlnaHQsIHN1bW1lcl9tZWRhbCRBZ2UpKQpuYW1lcyhTZXhfQ291bnRyeSkgPC0gYygiTmFtZSIsICdTZXgnLCJDb3VudHJ5IiwgIkhlaWdodCIsICJXZWlnaHQiLCAiQWdlIikKbnVtX2F0aGxldGVzID0gbWVyZ2UobnVtX2F0aGxldGVzLCBTZXhfQ291bnRyeSwgYnkgPSAnTmFtZScpCm51bV9hdGhsZXRlcyR3b25fbWVkYWw8LWlmZWxzZSgobnVtX2F0aGxldGVzJE51bWJlcj4wKSwgMSwgMCkKCm51bV9hdGhsZXRlczEgPSBudW1fYXRobGV0ZXNbc2FtcGxlKG5yb3cobnVtX2F0aGxldGVzKSwgMTAwMDApLCBdCgpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGxvdGx5KQoKbnVtX2F0aGxldGVzMSR3b25fbWVkYWwgPSBhcy5mYWN0b3IobnVtX2F0aGxldGVzMSR3b25fbWVkYWwpCnAgPC0gcGxvdF9seShkYXRhID0gbnVtX2F0aGxldGVzMSwgeCA9IH5XZWlnaHQsIHkgPSB+SGVpZ2h0LCBjb2xvcj0gfndvbl9tZWRhbCkgCnAKYGBgCgoKYGBge3J9CmdncGxvdGx5KHNleF9wbG90KQpgYGAKCgojIyMjIDYuIERhdGEgVGFibGUKClByZXBhcmUgYSBzZWxlY3RlZCBkYXRhc2V0IGFuZCBhZGQgYSBkYXRhdGFibGUgdG8gdGhlIG91dHB1dC4gTWFrZSBzdXJlIHRoZSBjb2x1bW5zIGFyZSBjbGVhcmx5IGxhYmVsbGVkLiBTZWxlY3QgdGhlIGFwcHJvcHJpYXRlIG9wdGlvbnMgZm9yIHRoZSBkYXRhIHRhYmxlIChlLmcuIHNlYXJjaCBiYXIsIHNvcnRpbmcsIGNvbHVtbiBmaWx0ZXJzIGV0Yy4pLiBTdWdnZXN0IHRvIHRoZSBlZGl0b3Igd2hpY2gga2luZCBvZiBpbmZvcm1hdGlvbiB5b3Ugd291bGQgbGlrZSB0byBwcm92aWRlIGluIGEgZGF0YSB0YWJsZSBpbiB0aGUgb25saW5lIHZlcnNpb24gb2YgdGhlIGFydGljbGUgYW5kIHdoeS4KYGBge3J9CnN1bW1lcl9tZWRhbDEgPSBkYXRhLmZyYW1lKHN1bW1lcl9tZWRhbCROYW1lLCAgc3VtbWVyX21lZGFsJFNleCwgc3VtbWVyX21lZGFsJENvdW50cnksIHN1bW1lcl9tZWRhbCRZZWFyLCBzdW1tZXJfbWVkYWwkTWVkYWwsIHN1bW1lcl9tZWRhbCRFdmVudCApCnN1bW1lcl9tZWRhbDEKbmFtZXMoc3VtbWVyX21lZGFsMSkgPSBjKCJOYW1lIiwgIlNleCIsICJDb3VudHJ5IiwgIlllYXIiLCJNZWRhbCIsICJFdmVudCIpCkRUIDwtICBkYXRhdGFibGUoc3VtbWVyX21lZGFsMSwgY2xhc3MgPSAnY2VsbC1ib3JkZXIgc3RyaXBlJywgcm93bmFtZXMgPUZBTFNFLCBvcHRpb25zID0gbGlzdCgKICBwYWdlTGVuZ3RoID0gMTAsIGF1dG9XaWR0aCA9IFRSVUUKKSwgZmlsdGVyID0gJ3RvcCcpCgpEVApEVDo6OkRUMkJTQ2xhc3MoJ2Rpc3BsYXknKQpEVDo6OkRUMkJTQ2xhc3MoYygnY29tcGFjdCcsICdjZWxsLWJvcmRlcicpKQpEVApgYGAKCg==